#include "cmus-rg.h"


void init_crg(TTF_Font **font, bool *render_change, track **cr_track, player **cr_player, bool *file_changed, int *frame) {
    *frame = 0;
    *file_changed = false;

    /* calculate max line width */
    int w;
    if (TTF_SizeUTF8(*font, "W", &w, NULL))
        fprintf(stderr, "TTF_SizeUTF8 error: %s\n", SDL_GetError());

    set_render_change(render_change);
    
    *cr_track = create_track((uint64_t) 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, (uint64_t) 0, (uint64_t) 0);
    *cr_player = create_player(NULL, NULL, (uint64_t) 0, (uint64_t) 0, (uint64_t) 0, false, false, false);
}

void cleanup_crg(track *cr_track, player *cr_player) {
    destroy_track(cr_track);
    destroy_player(cr_player);
}

void update_crg(cr_state *state) {
    /* lazily render */
    if (state->render_change || state->frame % 10 == 0) {
        /* query processing */
        /* update this even lazier, as it involves subprocess costs */
        if (state->render_change || state->frame % 60 == 0) {
            process_info(state->cr_track, state->cr_player, &state->previous_info_hash, &state->file_changed, &state->incomplete_parse);
        }
 
        draw_bg(&state->renderer, &state->render_change, BG);

        if (DEBUG)
            draw_frames(&state->renderer, &state->font, &state->render_change, state->frame);
       
        /* draw processed info */
        draw_info(&state->renderer, &state->font, &state->render_change, state->cr_track, state->cr_player);
        draw_buttons(&state->renderer, &state->render_change, state->root);
        if (state->file_changed) {
            state->file_changed = false;
            draw_cover_art(&state->renderer, &state->render_change, state->cr_track);
        }
    }

    state->frame++;
    if (state->frame >= 60)
        state->frame %= 60;
}

FILE* query_cmus() {
    FILE *fp = NULL;

    /* open command for reading */
    fp = popen("cmus-remote -Q 2>&1", "r");
    if (fp == NULL) {
        fprintf(stderr, "cmus-remote error: command not found or failed to run\n");
        exit(EXIT_FAILURE);
    }

    return fp;
}

void process_info(track *cr_track, player *cr_player, uint64_t *previous_info_hash, bool *file_changed, bool *incomplete_parse) {
    /* buffer */
    size_t max = 1024;
    char output[max];

    /* query data */
    FILE *fp = query_cmus();

    uint64_t info_hash = 0;
    /* read output one line at a time */
    while (fgets(output, sizeof(output) - 1, fp) != NULL) {
        info_hash += hash(output);

        // TODO: write streaming parser lol
        fill_track_or_player(cr_track, cr_player, output, max, file_changed, incomplete_parse);
    }

    /* close once done! */
    pclose(fp);

    /* skip doing anything if info hasn't changed */
    if (*previous_info_hash == info_hash)
        return;

    *previous_info_hash = info_hash;

    if (DEBUG) {
        print_track(cr_track);
        print_player(cr_player);
    }
}